package com.nus.fellowmark.modules.module.controller;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import com.nus.fellowmark.common.response.ServerResponseEntity;
import com.nus.fellowmark.entity.ModuleEntity;
import com.nus.fellowmark.entity.SupervisionEntity;
import com.nus.fellowmark.entity.UserEntity;
import com.nus.fellowmark.modules.module.dto.SupervisionDTO;
import com.nus.fellowmark.modules.module.service.ModuleService;
import com.nus.fellowmark.modules.module.service.SupervisionService;
import com.nus.fellowmark.modules.rbac.dto.UserRoleDTO;
import com.nus.fellowmark.modules.rbac.service.SysUserRoleMappingService;
import com.nus.fellowmark.modules.user.service.UserService;

import cn.dev33.satoken.annotation.SaCheckRole;
import cn.dev33.satoken.annotation.SaMode;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.nus.fellowmark.common.utils.PageUtils;



/**
 * 
 *
 * @author Chen Ruoyi
 * @email chenruoyisz@gmail.com
 * @date 2023-02-10  
 */
@RestController
@RequestMapping("supervision")
@CrossOrigin
public class SupervisionController {
    @Autowired
    SupervisionService supervisionService;

    @Autowired
    ModuleService moduleService;

    @Autowired
    UserService userService;


    @Autowired
    private SysUserRoleMappingService sysUserRoleMappingService;
    
    @ApiOperation("list supervision")
    @RequestMapping("/list")
    public ServerResponseEntity list(@RequestParam Map<String, Object> params){
        PageUtils page = supervisionService.queryPage(params);

        return ServerResponseEntity.success("page", page);
    }


    @ApiOperation("select supervision by id ")
    @RequestMapping("/info/{id}")
    public ServerResponseEntity info(@PathVariable("id") Integer id){
		SupervisionEntity supervision = supervisionService.getById(id);

        return ServerResponseEntity.success("supervision", supervision);
    }

    @SaCheckRole(value = {"staff"}, mode = SaMode.OR)
    @ApiOperation("select modules supervised by staff_id ")
    @RequestMapping("/staff/{id}")
    public ServerResponseEntity selectByStaffId(@PathVariable("id") Integer id){
		List<SupervisionEntity> supervision = supervisionService.getByStaffId(id);
        List<ModuleEntity> modulesSupervised = new ArrayList<ModuleEntity>();
        for(SupervisionEntity s : supervision){
            modulesSupervised.add(moduleService.getById(s.getModuleId()));
        }
        return ServerResponseEntity.success("modulesSupervised", modulesSupervised);
    }

    @SaCheckRole(value = {"staff"}, mode = SaMode.OR)
    @ApiOperation("select TAs appointed in module_id ")
    @RequestMapping("/module/{id}")
    public ServerResponseEntity selectByModuleId(@PathVariable("id") Integer id){
		List<SupervisionEntity> supervision = supervisionService.getByModuleId(id);
        List<UserEntity> tasAppointed = new ArrayList<UserEntity>();
        for(SupervisionEntity s : supervision){
            if (s.getTaBool() == 1) { // check if staff_id is a TA
                tasAppointed.add(userService.getById(s.getStaffId()));
            }
        }
        return ServerResponseEntity.success("TAs Appointed:", tasAppointed);
    }

    @SaCheckRole(value = {"staff", "admin", "super-admin"}, mode = SaMode.OR)
    @ApiOperation("save supervision")
    @RequestMapping("/save")
    public ServerResponseEntity save(@RequestBody SupervisionDTO supervisionDTO){
		// check if staff email exists
        if (userService.getByEmail(supervisionDTO.getEmail()) == null) {
            return ServerResponseEntity.showFailMsg(supervisionDTO.getEmail() + " does not exist!");
        }

        Integer moduleId = supervisionDTO.getModuleId();
        Integer userId = userService.getByEmail(supervisionDTO.getEmail()).getId();
        Integer taBool = supervisionDTO.getTaBool();

        // check if staff is already supervising this module
        SupervisionEntity supervisionExist = supervisionService.getByStaffIdAndModuleId(userId, moduleId);
        if (supervisionExist == null) {
            // save new supervision
            SupervisionEntity supervision = new SupervisionEntity();
            supervision.setModuleId(moduleId);
            supervision.setStaffId(userId);
            supervision.setTaBool(taBool);
            supervisionService.save(supervision);

            // update new supervisor to a staff (role_id = 3)
            UserRoleDTO userRoleDTO = new UserRoleDTO();
            userRoleDTO.setUserId(userId);
            userRoleDTO.setRoleid(3);
            sysUserRoleMappingService.updateById(userRoleDTO);
            
            return ServerResponseEntity.success();
        }
        else {
            return ServerResponseEntity.showFailMsg(supervisionDTO.getEmail() + " is already supervising this module!");
        }
    }

    @SaCheckRole(value = {"staff", "admin", "super-admin"}, mode = SaMode.OR)
    @ApiOperation("update supervision")
    @RequestMapping("/update")
    public ServerResponseEntity update(@RequestBody SupervisionEntity supervision){
		supervisionService.updateById(supervision);

        return ServerResponseEntity.success();
    }

    @SaCheckRole(value = {"staff", "admin", "super-admin"}, mode = SaMode.OR)
    @ApiOperation("delete supervision")
    @RequestMapping("/delete")
    public ServerResponseEntity delete(@RequestBody SupervisionDTO supervisionDTO){
		UserEntity supervisor = userService.getByEmail(supervisionDTO.getEmail());
        SupervisionEntity supervision = supervisionService.getByStaffIdAndModuleId(supervisor.getId(), supervisionDTO.getModuleId());
        supervisionService.removeById(supervision.getId());
        return ServerResponseEntity.success();
    }

}
